<?php 

/**
 * sfWidgetFormPropelChoice represents a choice widget for a model.
 *
 * @package    symfony
 * @subpackage widget
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
 * @version    SVN: $Id: sfWidgetFormPropelChoice.class.php 12803 2008-11-09 07:26:18Z fabien $
 */
class sfWidgetPropelLevels  extends sfWidgetFormPropelChoice
{
    public function configure($options = array(), $attributes = array()  ){

        $this->addOption('method_get_root_group' , null);
        $this->addOption('separtor',' __ ');
        $this->addRequiredOption('parent');


        //'getMenuItemRelatedByParentId';
        $this->addOption('method_get_children','get'.$options['model'].'sRelatedBy'.sfInflector::camelize($options['parent']));
        $this->addOption('method_cont_children','count'.$options['model'].'sRelatedBy'.sfInflector::camelize($options['parent']));

        parent::configure($options,$attributes);
    }

    public function render($name, $value = null, $attributes = array(), $errors = array())
    {

        //var_dump($value);exit;
        
        $choices_name = $name.'[choices]';
        $choices_id = $this->generateId($choices_name);
        $chk_box_name = $name.'[is_root]';
        $chk_box_id = $this->generateId($chk_box_name);
        $html = parent::render($choices_name, $value , $attributes , $errors );





        $lbl_attributes = array();
        $lbl_attributes['for'] = $chk_box_id;
        $lbl_attributes['style'] = 'display:inline;float:none;';

        $chck_box_lbl   = $this->renderContentTag('label','is root ?' , $lbl_attributes );

        $chk_attributes = array();
        $chk_attributes['name']    = $chk_box_name;
        $chk_attributes['id']    = $chk_box_id;
        $chk_attributes['type']    = 'checkbox';
        $chk_attributes['onclick'] = "if(this.checked) {$choices_id}.disabled = true ; else {$choices_id}.disabled = false ; ";
        $chck_box_lbl  .= $this->renderTag('input', $chk_attributes );


        $script = "var {$choices_id} = document.getElementById('".$choices_id."');";
        if(!$value){
            $script .= "document.getElementById('".$chk_box_id."').click();";
        }

        $script = '<script>'.$script.'</script>';

        return $html.$chck_box_lbl.$script;
    }


    public function getChoices()
    {
        $class = constant($this->getOption('model').'::PEER');

        $choices = array();
        if (false !== $this->getOption('add_empty'))
        {
            $choices[''] = true === $this->getOption('add_empty') ? '' : $this->getOption('add_empty');
        }

        $criteria = is_null($this->getOption('criteria')) ? new Criteria() : clone $this->getOption('criteria');
        if ($order = $this->getOption('order_by'))
        {
            $method = sprintf('add%sOrderByColumn', 0 === strpos(strtoupper($order[1]), 'ASC') ? 'Ascending' : 'Descending');
            $criteria->$method(call_user_func(array($class, 'translateFieldName'), $order[0], BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME));
        }

        $criteria->add(call_user_func(array($class, 'translateFieldName'), $this->getOption('parent'), BasePeer::TYPE_FIELDNAME  , BasePeer::TYPE_COLNAME ),null,Criteria::ISNULL );

        $objects = call_user_func(array($class, $this->getOption('peer_method')), $criteria, $this->getOption('connection'));

        $choices = $this->_rec_choices(array() , $objects , 0);


        return $choices;
    }


    protected function _rec_choices($choices , $objects , $level = 0){

        $class = constant($this->getOption('model').'::PEER');





        $methodKey = $this->getOption('key_method');
        if (!method_exists($this->getOption('model'), $methodKey))
        {
            throw new RuntimeException(sprintf('Class "%s" must implement a "%s" method to be rendered in a "%s" widget', $this->getOption('model'), $methodKey, __CLASS__));
        }

        $methodValue = $this->getOption('method');
        if (!method_exists($this->getOption('model'), $methodValue))
        {
            throw new RuntimeException(sprintf('Class "%s" must implement a "%s" method to be rendered in a "%s" widget', $this->getOption('model'), $methodValue, __CLASS__));
        }
        $methodCountChildren = $this->getOption('method_cont_children');
        if (!method_exists($this->getOption('model'), $methodCountChildren))
        {
            throw new RuntimeException(sprintf('Class "%s" must implement a "%s" method to be rendered in a "%s" widget', $this->getOption('model'), $methodCountChildren, __CLASS__));
        }
        $methodGetChildren = $this->getOption('method_get_children');
        if (!method_exists($this->getOption('model'), $methodGetChildren))
        {
            throw new RuntimeException(sprintf('Class "%s" must implement a "%s" method to be rendered in a "%s" widget', $this->getOption('model'), $methodGetChildren, __CLASS__));
        }


        $method_get_root_group = $this->getOption('method_get_root_group');


        foreach ($objects as $object)
        {
            /*

            */
            $count = $object->$methodCountChildren();

            if($method_get_root_group){


                if($count > 0){

                    $choices[$object->$method_get_root_group()->__toString()][$object->$methodKey()] = $this->drawLevel($object , $methodValue , $level).' -- ( '.$count.' children )';
                    $choices = $this->_rec_choices($choices , $object->$methodGetChildren() , $level + 1);

                }else{

                    if(empty($choices[$object->$method_get_root_group()->__toString()])){
                        $choices[$object->$method_get_root_group()->__toString()] = array();
                    }

                    $key_exsites = key_exists($object->$methodKey() , $choices[$object->$method_get_root_group()->__toString()]);

                    if(!$key_exsites){

                        $choices[$object->$method_get_root_group()->__toString()][$object->$methodKey()] = $this->drawLevel($object , $methodValue , $level);

                    }

                }

            }else{

                if($count > 0){

                    $choices[$object->$methodKey()] = $this->drawLevel($object , $methodValue , $level).' -- ( '.$count.' children )';
                    $choices = $this->_rec_choices($choices , $object->$methodGetChildren() , $level + 1);

                }else{

                    $key_exsites = key_exists($object->$methodKey() , $choices);
                    if(!$key_exsites){
                        $choices[$object->$methodKey()] = $this->drawLevel($object , $methodValue , $level);
                    }
                }
            }//not method group

        }

        return $choices;


    }

    public function drawLevel($obj , $valMethod , $level = 0){
        $separtor = $this->getOption('separtor');
        $text = $obj->$valMethod();

        while ($level > 0) {
            $text = $separtor.$text;
            $level--;
        }
        return $text;


    }


}